package md

import (
	"fmt"
	"log"
	"runtime"
	"strconv"
	"sync"
	"time"
)

// 编译版本
var (
	build   string
	compile string
)

// 服务名称
var (
	service string
)

// Git版本
var (
	branch   string
	revision string
)

// 服务器
var (
	hostname string
)

var (
	mu sync.Mutex
	md = Metadata{Customize: make(map[string]interface{})}
)

type Metadata struct {
	Service struct {
		Name string
	}
	Host struct {
		Port int
		Name string // 主机IP地址通过主机名配置
	}
	VersionControl struct {
		Branch   string
		Revision string
	}
	Compiler struct {
		Version   string
		BuildDate string
	}
	State struct {
		UpAt time.Time
	}
	Customize map[string]interface{}
}

func (md Metadata) Print() {
	log.Printf("build: %s %s on %s\n", md.Compiler.Version, md.Compiler.BuildDate, md.Host.Name)
	log.Printf("revision: %s-%s\n", md.VersionControl.Branch, md.VersionControl.Revision)
	if md.Host.Port != 0 {
		log.Printf("listening on: %s:%d\n", PublicIP, md.Host.Port)
	}
}

func Get() Metadata {
	return md
}

func GetTier() string {
	return md.VersionControl.Branch
}

func GetRevision() string {
	return md.VersionControl.Revision
}

func GetService() string {
	return md.Service.Name
}

func GetHost() string {
	return PublicIP
}

func GetHostname() string {
	return md.Host.Name
}

func GetListening() string {
	return strconv.Itoa(md.Host.Port)
}

func ListeningOn(port int) Metadata {
	md.Host.Port = port
	return md
}

func Register(key string, value interface{}) {
	mu.Lock()
	defer mu.Unlock()

	if _, ok := md.Customize[key]; ok {
		panic(fmt.Sprintf("duplicate metadata: %s", key))
	}
	md.Customize[key] = value
}

func init() {
	mu.Lock()
	defer mu.Unlock()

	md.Service.Name = service
	md.VersionControl.Branch = branch
	md.VersionControl.Revision = revision
	md.Compiler.Version = runtime.Version()
	md.Compiler.BuildDate = build
	md.Host.Name = hostname
	md.State.UpAt = time.Now()
	log.SetFlags(log.Lshortfile)
	log.SetPrefix(fmt.Sprintf("[%s] ", md.Service.Name))
}
